import unittest
from AStock.ASEvent import QThread
from AStock.ASEvent import Worker, Task
from AStock.ASEvent import Engine
import time


class TestCrawlJob(Worker):
    def run(self, event_data):
        event_type = event_data.get('event_type')
        if event_type == 'crawl_sina':
            print('crawl from sina')
            return 'result: crawl from sina'
        elif event_type == 'crawl_tencent':
            print('crawl from tencent')
            return 'result: crawl from tencent'
        else:
            print('unknown event type: {}'.format(event_type))
            return 'result: unknown event type: {}'.format(event_type)


class TestQThread(unittest.TestCase):

    def setUp(self):
        self.qt = QThread('abc')
        self.task_crawl_sina = Task(
            {'event_data': 'crawl_sina'},
            TestCrawlJob(),
            bind_event='abc',
            name='aaa',
            callback=print
        )
        self.task_crawl_tencent = Task(
            {'event_data': 'crawl_tencent'},
            TestCrawlJob(),
            bind_event='abc',
            name='bbb',
            callback=print
        )

    def tearDown(self):
        if self.qt.is_alive():
            self.qt.stop()
            self.qt.join()

    def testAll(self):
        print(self.qt)
        print('starting...')
        self.qt.start()

        print('putting...')
        self.qt.put(self.task_crawl_sina)

        print('putting...')
        self.qt.put(self.task_crawl_tencent)

        time.sleep(1)

        print('pausing...')
        self.qt.pause()

        print('putting...')
        self.qt.put(self.task_crawl_sina)

        print('putting...')
        self.qt.put(self.task_crawl_tencent)

        self.assertEqual(self.qt.qsize(), 2)

        print('resuming...')
        self.qt.resume()

        time.sleep(1)

        print('stopping...')
        self.qt.stop()

        self.assertEqual(self.qt.qsize(), 0)

        print('joining...')
        self.qt.join()

        time.sleep(3)


class TestEngine(unittest.TestCase):

    def setUp(self):

        self.task_crawl_sina = Task(
            {'event_data': 'crawl_sina'},
            TestCrawlJob(),
            bind_event='abc',
            name='aaa',
            callback=print
        )
        self.task_crawl_tencent = Task(
            {'event_data': 'crawl_tencent'},
            TestCrawlJob(),
            bind_event='abc',
            name='bbb',
            callback=print
        )
        self.task_crawl_other = Task(
            {'event_data': 'crawl_other'},
            TestCrawlJob(),
            bind_event='def',
            name='ccc',
            callback=print
        )

        self.task_crawl_other1 = Task(
            {'event_data': 'crawl_other1'},
            TestCrawlJob(),
            name='ddd',
            callback=print
        )

        self.engine = Engine()

    def tearDown(self):
        if self.engine.is_alive():
            self.engine.stop_all()
            self.engine.join_all()

    def testAll(self):
        print(self.engine)

        print('starting...')
        self.engine.start()

        print('creating event abc...')
        self.engine.create_event('abc')
        print('starting event abc...')
        self.engine.start_event('abc')

        print('creating event def...')
        self.engine.create_event('def')
        print('starting event def...')
        self.engine.start_event('def')

        self.assertEqual(self.engine.event_num(), 2)

        print('putting to engine queue...')
        self.engine.put(self.task_crawl_sina)

        print('putting to event thread queue...')
        self.engine.run_task(self.task_crawl_tencent)

        print('putting to event thread queue...')
        self.engine.run_task(self.task_crawl_other)

        print('putting to engine queue...')
        self.engine.put(self.task_crawl_other1)

        time.sleep(1)

        print('pausing...')
        self.engine.pause()

        print('putting to engine queue...')
        self.engine.put(self.task_crawl_sina)

        print('putting to event thread queue...')
        self.engine.run_task(self.task_crawl_tencent)

        print('putting to event thread queue...')
        self.engine.run_task(self.task_crawl_other)

        self.assertEqual(self.engine.qsize(), 1)

        print('resuming engine...')
        self.engine.resume()

        time.sleep(1)

        print('stopping...')
        self.engine.stop_all()

        self.assertEqual(self.engine.qsize(), 0)

        print('joining...')
        self.engine.join_all()

        time.sleep(3)
